import {
    DesktopOutlined,
    FileOutlined,
    PieChartOutlined,
    TeamOutlined,
    UserOutlined,
  } from '@ant-design/icons';
import type { MenuProps } from 'antd';
import { Menu } from 'antd';
import { useNavigate, useLocation } from 'react-router-dom';
import React, { useState } from 'react';

type MenuItem = Required<MenuProps>['items'][number];

// 下面这个函数和items数组是antd提供的写法，侧边菜单栏的菜单项由下面决定
// getItem 是一个函数，接收参数，返回一个对象
function getItem(
  label: React.ReactNode,
  key: React.Key,
  icon?: React.ReactNode,
  children?: MenuItem[],
): MenuItem {   // MenuItem 是当前这个函数的 ts 数据类型
  return {
    key,
    icon,
    children,
    label,
  } as MenuItem;
}
// items 是一个数组(侧边菜单栏下的每一个菜单项是根据这个数组生成)，数组中装的是 getItem函数，分别给函数传递不同的值，而这个函数返回的是一个对象，所以实际上这个数组中装的是都是对象
const items: MenuItem[] = [
    getItem('栏目 1', '/page1', <PieChartOutlined />),
    // 这里调用 getItem 方法，传递的参数会被返回在一个对象中
    getItem('栏目 2', '/page2', <DesktopOutlined />),
    getItem('栏目 3', 'page3', <UserOutlined />, [
      getItem('栏目 301', '/page3/page301'),
      getItem('栏目 302', '/page3/page302'),
      getItem('栏目 303', '/page3/page303'),
    ]),
    getItem('栏目 4', 'page4', <TeamOutlined />, [
      getItem('栏目 401', '/page4/page401'),
      getItem('栏目 402', '/page4/page402')
    ]),
    getItem('栏目 5', '/page5', <FileOutlined />),
];

// 下面这个items数组是自己的写法，上面那个函数和数组是antd提供的写法，二者效果一样
/* const items: MenuItem[] = [
    {
      label: '栏目 1',
      key: '/page1',
      icon: <PieChartOutlined />
    },
    {
      label: '栏目 2',
      key: '/page2',
      icon: <DesktopOutlined />
    },
    {
      label: '栏目 3',
      key: 'page3',
      icon: <UserOutlined />,
      children:[
        {
          label: '栏目 301',
          key: '/page3/page301',
        },
        {
          label: '栏目 302',
          key: '/page3/page302',
        },
        {
          label: '栏目 303',
          key: '/page3/page303',
        }
      ]
    },
    {
      label: '栏目 4',
      key: 'page4',
      icon: <TeamOutlined />,
      children:[
        {
          label: '栏目 401',
          key: '/page4/page401',
        },
        {
          label: '栏目 304',
          key: '/page4/page402',
        }
      ]
    },
    {
      label: '栏目 5',
      key: '/page5',
      icon: <FileOutlined />
    }
  ] */
  

const Comp: React.FC = () => {
    // firstOpenKey 中装的是当前的路由路径
    let firstOpenKey:string = "";
    // useLocation方法可以获取到当前的路由路径，
    const currentRoute = useLocation()
    console.log(currentRoute.pathname);  // currentRoute它返回一个对象，对象中的pathname就是当前的路由路径
    // useNavigate方法用于路由重定向
    const navigateTo = useNavigate()

    function findKey(obj:{key:string}){  // 这个函数配合find方法，如果items数组中的对象元素的children属性对象中的key属性值与currentRoute.pathname当前路由路径相同，那么就返回true，反之，返回false
        return obj.key === currentRoute.pathname;
    }
    for(let i=0;i<items.length;i++){
        // 下面是判断items中的对象元素中是否存在 children 对象元素，并且children对象元素的长度是否大于0，并且利用find方法配合findKey函数检查children对象中的key是否等于当前路由路径currentRoute.pathname
        if(items[i]['children'] && items[i]['children'].length>0 && items[i]['children'].find(findKey)){
            firstOpenKey = items[i].key as string; // 将这个children所在的items对象元素的key值赋值给firstOpenKey
            break;
        }
    }

    // 创建一个数组，用于决定菜单栏下的哪些下拉菜单项处于展开状态，如果初始值为空，说明一开始让所有下拉菜单都不展开
    // 这里将openKeys的初始值赋值为firstOpenKey，是为了如果浏览器刷新的时候，路由路径对应的是一个下拉菜单中的菜单项，那么就让这个下拉菜单呈展开状态
    const [openKeys, setOpenKeys] = useState([firstOpenKey]);

    // 菜单项的点击事件回调
    const menuClick = (e:{key:string})=>{
        // 这里的 e.key 获取到的是上面 items 数组中 getItem 中的第二个参数，上面将第二个参数设置为对应的路由路径，方便实现点击菜单跳转对应的路由路径
        console.log(e.key);
        
        // 点击菜单跳转到对应的路由   这种方式叫做编程式路由导航
        // Router6用Navigate取代了Redirect重定向
        navigateTo(e.key)   // 利用 Navigate 将路由路径重定向为指定路径
    }

    // 下拉菜单项状态改变的事件回调
    const handleChange = (keys:string[])=>{
        // keys 是一个数组，里面记录的是当前菜单栏下有哪些下拉菜单项是展开状态的，它会把展开的下拉菜单项在上面的items数组中的对应的getItem中的第二个参数记录下来
        console.log(keys);
        // 调用setOpenKeys方法修改openKeys数组，将openKeys修改成一个新数组，里面只装有keys数组中的最后一个元素
        // keys 中的最后一个元素是当前最近点击的下拉菜单项对应的getItem中的第二个参数
        // 将这个元素给予openKeys数组，而opensKeys数组决定当前菜单栏下哪个下拉菜单处于展开状态
        // 这样做就可以实现，点击展开一个下拉菜单，其他下拉菜单会处于折叠状态，不会有多个下拉菜单同时处于展开状态
        setOpenKeys([keys[keys.length-1]])// 创建一个数组，用于决定菜单栏下的哪些下拉菜单项处于展开状态，如果初始值为空，说明一开始让所有下拉菜单都不展开
    }

    return (
        <Menu 
            theme="dark" 
            // 下面这个是设置默认高亮的下拉菜单项，它要填写的是指定菜单项对应的getItem方法中的第二个参数
            defaultSelectedKeys={[currentRoute.pathname]}   // currentRoute.pathname获取的是当前的路由路径，而当前我规定的菜单项对应的getItem方法中的第二个参数key就是它要跳转的路由路径，所以只要把当前的路由路径传递传递给defaultSelectedKeys，那么打开项目后，路径是那个，它对应的菜单项就会处于高亮状态
            mode="inline"
            items={items} 
            onClick={menuClick}
            // onOpenChange是当前菜单栏中下拉菜单项的状态发生改变后会触发的事件，也就是下拉菜单项折叠状态发生改变后就会触发
            onOpenChange={handleChange}
            // openKeys是用于决定当前菜单栏下的哪些下拉菜单项处于展开状态
            openKeys={openKeys}
        />
    )
}

export default Comp